#include "func_uart.h"
#include "string.h"
#include "usb_com.h"
#include "mem_malloc.h"

extern UART_HandleTypeDef huart1;
unsigned char *uartSend;
unsigned char uartRec[BUFF_SIZE];
unsigned char *uartRecTemp;
extern DMA_HandleTypeDef hdma_usart1_rx;
static unsigned char uartLen;


/// @brief usb设定串口参数
/// @param cmd
/// @param subCmd
/// @param data
void uart_set_param(unsigned char cmd, unsigned char subCmd, unsigned char *data)
{
    unsigned long baud = 0;
    HAL_UART_DeInit(&huart1);

    baud = (data[5] << 24) + (data[6] << 16) + (data[7] << 8) + (data[8]);

    huart1.Instance = USART1;
    huart1.Init.BaudRate = baud;
    switch (data[9])
    {
        case 0:
            huart1.Init.Parity = UART_PARITY_NONE;
            break;
        case 1:
            huart1.Init.Parity = UART_PARITY_ODD;
            break;
        case 2:
            huart1.Init.Parity = UART_PARITY_EVEN;
            break;

        default:
            break;
    }
    switch (data[10])
    {
        case 0:
            huart1.Init.StopBits = UART_STOPBITS_1;
            break;
        case 1:
            huart1.Init.StopBits = UART_STOPBITS_2;
            break;

        default:
            break;
    }

    switch (data[11])
    {
        case 0:
            huart1.Init.WordLength = UART_WORDLENGTH_8B;
            break;
        case 1:
            huart1.Init.WordLength = UART_WORDLENGTH_9B;
            break;

        default:
            break;
    }

    huart1.Init.Mode = UART_MODE_TX_RX;
    huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
    huart1.Init.OverSampling = UART_OVERSAMPLING_16;
    if (HAL_UART_Init(&huart1) != HAL_OK)
    {
        usb_cmd(COMM_UART, COMM_SUB_UART_SET_PARAM, (void *)COM_FAIL);
    }
    else
    {
			uart_rec_start();
        usb_cmd(COMM_UART, COMM_SUB_UART_SET_PARAM, (void *)COM_OK);
    }
}

/// @brief usb接收到需要发送的数据
/// @param cmd
/// @param subCmd
/// @param data
void uart_send_data(unsigned char cmd, unsigned char subCmd, unsigned char *data)
{
    m_malloc(uartSend, data[2] - 6);
    if (uartSend == 0)
    {
        usb_cmd(COMM_UART, COMM_SUB_UART_SEND, (void *)COM_MEM);
    }
    else
    {
			memcpy(uartSend,&data[5], data[2] - 6);
        if (HAL_UART_Transmit_IT(&huart1, uartSend, data[2] - 6) == HAL_OK)
        {
            usb_cmd(COMM_UART, COMM_SUB_UART_SEND, (void *)COM_OK);
            return;
        }
        else
        {
            m_free(uartSend);
            usb_cmd(COMM_UART, COMM_SUB_UART_SEND, (void *)COM_FAIL);
        }

    }

}

/// @brief usb上传接收到的数据
/// @param cmd
/// @param subCmd
/// @param param
void uart_rec_update(unsigned char cmd, unsigned char subCmd, void *param)
{
    unsigned char sendData[USB_PORT_SIZE] = {0};
    unsigned char len = (unsigned char)param;
    sendData[0] = 0x55;
    sendData[1] = 0xaa;
    sendData[2] = len + 6;
    sendData[3] = COMM_UART;
    sendData[4] = COMM_SUB_UART_REC;
    if (uartRecTemp)
    {
        memcpy(&sendData[5], uartRecTemp, len);
        m_free(uartRecTemp);
    }

    sendData[len + 5] = chksum(sendData, len + 6);
    usb_send(sendData, len + 6);
}

/// @brief 硬件串口接收到数据
/// @param data
/// @param len
void uart_rec_data(unsigned char *data, unsigned long len)
{
    uartLen = len;
    m_malloc(uartRecTemp, len);
    if (uartRecTemp == 0)
    {
        usb_cmd(COMM_UART, COMM_SUB_UART_REC, (void *)COM_MEM);
    }
    else
    {
        memcpy(uartRecTemp, data, len);
        usb_cmd(COMM_UART, COMM_SUB_UART_REC, (void *)uartLen);
    }

}
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
{
    m_free(uartSend);
}
void uart_rec_start()
{
    HAL_UART_Receive_DMA(&huart1, uartRec, BUFF_SIZE);
}
void USAR_UART_IDLECallback(UART_HandleTypeDef *huart)
{
    if (huart->Instance == USART1)
    {
        HAL_UART_DMAStop(&huart1);
        uint8_t data_length  = BUFF_SIZE - __HAL_DMA_GET_COUNTER(&hdma_usart1_rx);
        if (data_length <= BUFF_SIZE)
        {
            uart_rec_data(uartRec, data_length);         // 将接收到的数据再发出
            memset(uartRec, 0, BUFF_SIZE);                             // 清除接收缓存
            HAL_UART_Receive_DMA(&huart1, uartRec, BUFF_SIZE); // 接收完毕后重新接收
        }
        else  // 接收数据长度大于BUFF_SIZE，错误处理
        {

        }
    }
}
